package org.m8.auth.handler.username;

import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.m8.auth.handler.AbstractAuthLoginHandler;
import org.m8.auth.handler.AuthLoginHandlerRegistry;
import org.m8.auth.controller.vo.AuthLoginRespVO;
import org.m8.user.model.User;
import org.m8.user.model.UserService;
import org.m8.util.JsonUtil;
import org.m8.util.StatusEnum;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.Objects;

import static org.m8.util.exception.ServiceExceptionUtil.exception;
import static org.m8.util.exception.emnus.GlobalErrorCodeConstants.AUTH_LOGIN_BAD_CREDENTIALS;

/**
 * 用户名登录
 *
 * @author yidanjun
 * @date 2024/9/7
 **/
@Service
@Slf4j
public class UserNameAuthLoginHandler extends AbstractAuthLoginHandler {



    @Resource
    private UserService userService;

    @Resource
    private PasswordEncoder passwordEncoder;

    private static final String AUTH_LOGIN_TYPE = "username";
    @Override
    protected void init() {
        AuthLoginHandlerRegistry.getInstance().register(AUTH_LOGIN_TYPE, this);
    }
    @Override
    public <R extends AuthLoginRespVO> R login(Map<String, Object> req) {
        UserNameAuthLoginReqVO userNameAuthLoginReqVO = JsonUtil.parse(req, UserNameAuthLoginReqVO.class);

        User user = authenticate(userNameAuthLoginReqVO.getUsername(), userNameAuthLoginReqVO.getPassword());
        return (R)createTokenAfterLoginSuccess(user);
    }

    private User authenticate(String userName, String password){
        User user = userService.getByUsername(userName);
        if (user == null) {
            log.error("用户不存在，userName: {}", userName);
            throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
        }

        if (!passwordEncoder.matches(password, user.getPassword())){
            log.error("密码错误，userName: {}", userName);
            throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
        }

        if (!Objects.equals(user.getStatus(), StatusEnum.VALID.getValue())){
            log.error("用户状态异常，userName: {}", userName);
            throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
        }

        return user;
    }
}
